home *** CD-ROM | disk | FTP | other *** search
/ Freelog 117 / FreelogNo117-OctobreNovembre2013.iso / Programmation / jedit / jedit5.1.0install.exe / {app} / macros / Properties / Create_Plugin_Announcement.bsh next >
Text File  |  2013-07-28  |  17KB  |  443 lines

  1. /*
  2.  * Create_plugin_release_text.bsh - a BeanShell macro script for the
  3.  * jEdit text editor - Parses a plugin's properties file to create the
  4.  * text for a plugin submission
  5.  * Copyright ( C ) 2006 Jeffrey Hoyt
  6.  * jchoyt@jedit.org
  7.  * Eric Berry <elberry@users.sourceforge.net> (version checking 2010)
  8.  *
  9.  * This program is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License
  11.  * as published by the Free Software Foundation; either version 2
  12.  * of the License, or any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  22.  *
  23.  */
  24.  
  25.  
  26. // import statements
  27. import javax.swing.border.*;
  28. import org.gjt.sp.util.Log;
  29. import java.util.Comparator;
  30.  
  31. public class PluginDependency
  32. {
  33.     public String className;
  34.     public String simpleName;
  35.     public String version;
  36.     
  37.     public PluginDependency(String cn, String v)
  38.     {
  39.         className = cn;
  40.         version = v;
  41.         simpleName = jEdit.getProperty("plugin." + cn + ".name");
  42.         if(simpleName != null)
  43.         {
  44.             simpleName = simpleName.trim();
  45.         }
  46.         if(simpleName == null || simpleName.length() <= 0)
  47.         {
  48.             int lastDotIndex = cn.lastIndexOf(".");
  49.             simpleName = cn.substring(lastDotIndex + 1);
  50.         }
  51.         Log.log(Log.DEBUG, this, "new PluginDependency class: " + className + " | name: " + simpleName + " | version: " + version);
  52.     }
  53. }
  54.  
  55. public class PluginDependencyNameComparator implements Comparator
  56. {
  57.     public int compare(Object o1, Object o2)
  58.     {
  59.         PluginDependency pd1 = (PluginDependency)o1;
  60.         PluginDependency pd2 = (PluginDependency)o2;
  61.         return pd1.simpleName.compareTo(pd2.simpleName);
  62.     }
  63. }
  64.  
  65. // main routine
  66. void pluginTextDialog( View view, Buffer buffer )
  67. {
  68.     this.view = view;
  69.     this.buffer=buffer;
  70.  
  71.     File propsFile = new File( buffer.getPath() );
  72.     Properties props = new Properties();
  73.     InputStream in = new FileInputStream( propsFile );
  74.     try
  75.     {
  76.         props.load( in );
  77.     }
  78.     finally
  79.     {
  80.         in.close();
  81.     }
  82.  
  83.     //setup the strings we are interested in and can get from the props file
  84.     String fileName = propsFile.getName();
  85.     String pluginName = fileName.substring( 0, fileName.indexOf( '.' ) );
  86.     String version = null;
  87.     String jEditDependency = null;
  88.     String javaDependency = null;
  89.     String activate = null;
  90.     ArrayList pluginDependencies = new ArrayList();
  91.     ArrayList optionalPluginDependencies = new ArrayList();
  92.     String announcement, shortDescription, source;
  93.     String longDescription="";
  94.     String classname=null;
  95.     String longDescriptionFileName=null;
  96.  
  97.     //extract the properties we care about
  98.     String start = "plugin.";
  99.     for ( Enumeration e = props.keys(); e.hasMoreElements() ; )
  100.     {
  101.         String key = ( String ) e.nextElement();
  102.         // Log.log( Log.DEBUG, this, "Parsing key: " + key );
  103.         if( key.startsWith( start ) )
  104.         {
  105.             if( key.endsWith( ".activate" ) )
  106.             {
  107.                 activate = props.getProperty( key );
  108.             }
  109.             else if( key.endsWith( ".version" ) )
  110.             {
  111.                 version = props.getProperty( key );
  112.             }
  113.             else if( key.indexOf( ".depend." ) != -1 )
  114.             {
  115.                 String value = props.getProperty( key ).trim();
  116.                 String[] parts = value.split( " " );
  117.                 if( parts.length < 2 )
  118.                 {
  119.                     Macros.error( view, "Badly constructed dependency ( " + value + " ).  All dependencies must have at least 2 parts" );
  120.                 }
  121.                 if( parts[0].equals( "jedit" ) )
  122.                 {
  123.                     jEditDependency = parts[1];
  124.                 }
  125.                 else if( parts[0].equals( "jdk" ) )
  126.                 {
  127.                     javaDependency = parts[1];
  128.                 }
  129.                 else if( parts[0].equals( "plugin" ) )
  130.                 {
  131.                     Log.log(Log.DEBUG, this, "required plugin name - class: " + parts[1] + " | name: " + jEdit.getProperty("plugin." + parts[1] + ".name"));
  132.                     pluginDependencies.add(new PluginDependency(parts[1], parts[2]));
  133.                 }
  134.                 else if( parts[0].equals( "optional" ) && parts[1].equals( "plugin" ) )
  135.                 {
  136.                     Log.log(Log.DEBUG, this, "optional plugin name - class: " + parts[2] + " | name: " + jEdit.getProperty("plugin." + parts[2] + ".name"));
  137.                     optionalPluginDependencies.add(new PluginDependency(parts[2], parts[3]));
  138.                 }
  139.                 else
  140.                 {
  141.                     Macros.error( view, "Unexpected dependency ( " + value + " ).  See the javadoc of org.gjt.sp.jedit.EditPlugin" );
  142.                 }
  143.             }
  144.             else if(key.endsWith(".longdescription") )
  145.             {
  146.                 longDescriptionFileName = props.getProperty( key );
  147.             }
  148.             else if(key.endsWith(".description") )
  149.             {
  150.                 shortDescription = props.getProperty( key );
  151.             }
  152.             else if(key.endsWith(".name") )
  153.             {
  154.                 if (props.getProperty( key ).equals(pluginName))
  155.                 {
  156.                     classname = key.substring( start.length(), key.length() - 5 );
  157.                     // Macros.error( view, "Classname is " + classname );
  158.                 }
  159.             }
  160.         }
  161.     }
  162.     // Macros.error( view, "Parsing complete" );
  163.  
  164.     if( javaDependency==null )
  165.     {
  166.         Macros.error( view, "You must supply a JDK dependency.  Please add it and rerun the macro." );
  167.         return;
  168.     }
  169.     if( jEditDependency==null )
  170.     {
  171.         Macros.error( view, "You must supply a jEdit dependency.  Please add it and rerun the macro." );
  172.         return;
  173.     }
  174.     if( shortDescription==null )
  175.     {
  176.         Macros.error( view, "You must supply a short description in the plugin." + classname + ".description property.  Please add it and rerun the macro." );
  177.         return;
  178.     }
  179.     if( longDescriptionFileName==null )
  180.     {
  181.         longDescriptionFileName = "description.html";
  182.         // Macros.error(view, "setting default long description file");
  183.     }
  184.  
  185.     //load the long description
  186.     File descriptionFile = new File( new File(buffer.getPath()).getParent(), longDescriptionFileName );
  187.     if(!descriptionFile.exists())
  188.     {
  189.         Macros.error( view, "You must supply a long description in a file located at " + descriptionFile.getPath() + ".  Please create it and rerun the macro." );
  190.         return;
  191.     }
  192.     BufferedReader reader = new BufferedReader( new FileReader( descriptionFile ) );
  193.     try
  194.     {
  195.         String line;
  196.         while( (line = reader.readLine())!=null )
  197.         {
  198.             longDescription = longDescription + line + "\n";
  199.         }
  200.     }
  201.     finally
  202.     {
  203.         reader.close();
  204.     }
  205.  
  206.     // create dialog object and set its features
  207.     title = "Create Plugin Announcement";
  208.     dialog = new JDialog( view, title, false );
  209.     content = new JPanel( new BorderLayout() );
  210.     content.setBorder( new EmptyBorder( 12, 12, 12, 12 ) );
  211.     dialog.setContentPane( content );
  212.  
  213.     // add to the dialog a panel containing the text fields for
  214.     // entry of the prefix and suffix text
  215.     propsPanel = new JPanel( new GridLayout( 5 + pluginDependencies.size() + optionalPluginDependencies.size() , 2, 2, 6 ) );
  216.     propsPanel.add( new JLabel( "Plugin name" ) );
  217.     propsPanel.add( new JLabel( pluginName ) );
  218.     propsPanel.add( new JLabel( "Plugin version" ) );
  219.     propsPanel.add( new JLabel( version ) );
  220.     propsPanel.add( new JLabel( "Activates" ) );
  221.     propsPanel.add( new JLabel( activate ) );
  222.     propsPanel.add( new JLabel( "jEdit Dependency" ) );
  223.     propsPanel.add( new JLabel( jEditDependency ) );
  224.     propsPanel.add( new JLabel( "JDK Dependency" ) );
  225.     propsPanel.add( new JLabel( javaDependency ) );
  226.     PluginDependencyNameComparator comparator = new PluginDependencyNameComparator();
  227.     Collections.sort(pluginDependencies, comparator);
  228.     Collections.sort(optionalPluginDependencies, comparator);
  229.     for( int i=0; i<pluginDependencies.size(); i++ )
  230.     {
  231.         propsPanel.add( new JLabel( "Depends on" ) );
  232.         PluginDependency requiredPlugin = pluginDependencies.get( i );
  233.         propsPanel.add( new JLabel( requiredPlugin.simpleName + " " + requiredPlugin.version ) );
  234.     }
  235.     for( int i=0; i<optionalPluginDependencies.size(); i++ )
  236.     {
  237.         propsPanel.add( new JLabel( "Optional" ) );
  238.         PluginDependency optionalPlugin = optionalPluginDependencies.get( i );
  239.         propsPanel.add( new JLabel( optionalPlugin.simpleName + " " + optionalPlugin.version ) );
  240.     }
  241.     content.add( propsPanel, "Center" );
  242.  
  243.     //add areas for source location, Announcement, Short Description, and Long Description
  244.     descriptionPanel = new JPanel();
  245.     descriptionPanel.setLayout( new BoxLayout( descriptionPanel, BoxLayout.Y_AXIS ) );
  246.     descriptionPanel.setBorder(new EmptyBorder(12, 5, 0, 5));
  247.  
  248.     descriptionPanel.add( new JLabel( "Source Code Location (SVN and tag, or URL): " ) );
  249.     sourceArea = new JEditorPane();
  250.     sourceArea.setText("Source code is in SVN with the tag XXXX (no SVN release numbers, please)");
  251.     sourceArea.setPreferredSize( new Dimension( 250, 36 ) );
  252.     descriptionPanel.add( new JScrollPane( sourceArea ) );
  253.  
  254.     descriptionPanel.add( new JLabel( "Announcement: " ) );
  255.     announcementArea = new JEditorPane();
  256.     announcementArea.setPreferredSize( new Dimension( 250, 120 ) );
  257.     descriptionPanel.add( new JScrollPane( announcementArea ) );
  258.  
  259.     descriptionPanel.add( new JLabel( "Short Description ( for new plugins or updated descriptions only ): " ) );
  260.     shortDescriptionArea = new JEditorPane("text/plain", shortDescription);
  261.     shortDescriptionArea.disable();
  262.     shortDescriptionArea.setPreferredSize( new Dimension( 250, 72 ) );
  263.     descriptionPanel.add( new JScrollPane( shortDescriptionArea ) );
  264.  
  265.     descriptionPanel.add( new JLabel( "Long Description ( for new plugins or updated descriptions only ): " ) );
  266.     longDescriptionArea = new JEditorPane("text/plain", longDescription);
  267.     longDescriptionArea.disable();
  268.     longDescriptionArea.setPreferredSize( new Dimension( 250, 120 ) );
  269.     descriptionPanel.add( new JScrollPane( longDescriptionArea ) );
  270.  
  271.     //add buttons to description panel
  272.     buttonPanel = new JPanel();
  273.     buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.X_AXIS ) );
  274.     ok = new JButton( "Create Announcement" );
  275.     buttonPanel.add( ok );
  276.     cancel = new JButton( "Cancel" );
  277.     buttonPanel.add( cancel );
  278.     descriptionPanel.add( buttonPanel );
  279.     content.add( descriptionPanel, "South" );
  280.  
  281.     // register this method as an ActionListener for
  282.     // the buttons and text fields
  283.     ok.addActionListener( this );
  284.     cancel.addActionListener( this );
  285.  
  286.     // locate the dialog in the center of the
  287.     // editing pane and make it visible
  288.     dialog.pack();
  289.     dialog.setLocationRelativeTo( view );
  290.     dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
  291.     dialog.setVisible( true );
  292.  
  293.     // this method will be called when a button is clicked
  294.     // or when ENTER is pressed
  295.     void actionPerformed( e )
  296.     {
  297.         if( e.getSource() != cancel )
  298.         {
  299.               if(validateVersions()) {
  300.                     createAnnouncement();
  301.               }
  302.         }
  303.         dialog.dispose();
  304.     }
  305.  
  306.     void createAnnouncement()
  307.     {
  308.         announcement = announcementArea.getText();
  309.         shortDescription = shortDescriptionArea.getText();
  310.         longDescription = longDescriptionArea.getText();
  311.         source = sourceArea.getText();
  312.         StringBuffer ret = new StringBuffer();
  313.         ret.append( "Paste the text below into the Plugin Central Submission Tracker at https://sourceforge.net/tracker/?group_id=588&atid=625093\n" );
  314.         ret.append( "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
  315.         ret.append( "\n{{{ " );
  316.         ret.append( pluginName );
  317.         ret.append( " " );
  318.         ret.append( version );
  319.         ret.append( "\n    Source: " );
  320.         ret.append( source );
  321.         ret.append( "\n    Announcement: " + announcement.replaceAll("\n", "\n        " ) );
  322.         ret.append( "\n    Requires Java " );
  323.         ret.append( javaDependency );
  324.         ret.append( "\n    Requires jEdit " );
  325.         ret.append( jEditDependency );
  326.         if( pluginDependencies.size() > 0 )
  327.         {
  328.             ret.append( "\n    Required plugins: " );
  329.             for( int i=0; i<pluginDependencies.size(); i++ )
  330.             {
  331.                 ret.append( "\n        " );
  332.                 PluginDependency plugin = pluginDependencies.get( i );
  333.                 ret.append( plugin.simpleName + " " + plugin.version + " (" + plugin.className + ")"  );
  334.             }
  335.         }
  336.         if( optionalPluginDependencies.size() > 0 )
  337.         {
  338.             ret.append( "\n    Optional plugins: " );
  339.             for( int i=0; i<optionalPluginDependencies.size(); i++ )
  340.             {
  341.                 ret.append( "\n        " );
  342.                 PluginDependency plugin = optionalPluginDependencies.get( i );
  343.                 ret.append( plugin.simpleName + " " + plugin.version + " (" + plugin.className + ")"  );
  344.             }
  345.         }
  346.         if( shortDescription!=null && !shortDescription.equals( "" ) )
  347.         {
  348.             ret.append( "\n    \n    Short Description: " + shortDescription );
  349.         }
  350.         if( longDescription!=null && !longDescription.equals( "" ) )
  351.         {
  352.             ret.append( "\n    \n    Long Description: " + longDescription );
  353.         }
  354.         ret.append( " }}}" );
  355.         newbuf = jEdit.newFile( view );
  356.         newbuf.insert( 0, ret.toString() );
  357.     }
  358.     
  359.     boolean pluginIsNotInstalled(PluginDependency dependency, String installed) {
  360.         if(installed != null) {
  361.             installed = installed.trim();
  362.             if(!installed.equals(dependency.version))
  363.             {
  364.                 return true;
  365.             }
  366.         } else {
  367.             return true;
  368.         }
  369.         return false;
  370.     }
  371.     
  372.     boolean validateVersions()
  373.     {
  374.          boolean valid = true;
  375.          StringBuilder builder = new StringBuilder();
  376.          builder.append(
  377.               "There are some inconsistencies in your plugin's requirements. The\n" +
  378.               "version numbers below don't match what you are working with in\n" +
  379.               "your installation of jEdit.\n\n");
  380.          
  381.          // check jEdit dependency against running build.
  382.          String build = jEdit.getBuild();
  383.          if(!build.equals(jEditDependency))
  384.          {
  385.               valid = false;
  386.               builder.append("      jEdit - Required: " + jEditDependency + " - Running: " + build + "\n");
  387.          }
  388.          
  389.          // check required plugin dependencies.
  390.          for( int i = 0; i < pluginDependencies.size(); i++ )
  391.          {
  392.              PluginDependency plugin = pluginDependencies.get(i);
  393.              String installed = jEdit.getProperty("plugin." + plugin.className + ".version");
  394.              if(pluginIsNotInstalled(plugin, installed)) {
  395.                  valid = false;
  396.                  builder.append("      " + plugin.simpleName + " - Required: " + plugin.version + " - Running: " + installed + "\n");
  397.              }
  398.          }
  399.          
  400.          // check optional plugin dependencies.
  401.          for( int i = 0; i < optionalPluginDependencies.size(); i++ )
  402.          {
  403.              PluginDependency plugin = optionalPluginDependencies.get(i);
  404.              String installed = jEdit.getProperty("plugin." + plugin.className + ".version");
  405.              if(pluginIsNotInstalled(plugin, installed)) {
  406.                  valid = false;
  407.                  builder.append("      " + plugin.simpleName + " - Optional: " + plugin.version + " - Running: " + installed + "\n");
  408.              }
  409.          }
  410.          
  411.          if(!valid)
  412.          {
  413.               builder.append("\n\n" +
  414.                    "Note that your plugin will be tested against the latest released\n" +
  415.                    "versions of jEdit and your plugin's dependencies before it is\n" +
  416.                    "released.\n\n" +
  417.                    "Do you want to continue creating this announcement, or would you\n" +
  418.                    "like to cancel it, and update the version numbers?\n\n" +
  419.                    "       \"Yes\" to create announcement as is.\n" +
  420.                    "       \"No\" to cancel and update props.");
  421.               int choice = JOptionPane.showConfirmDialog(
  422.                                        view,
  423.                                        builder.toString(),
  424.                                        "Versions don't match",
  425.                                        JOptionPane.YES_NO_OPTION,
  426.                                        JOptionPane.WARNING_MESSAGE);
  427.               
  428.               // if user's chosen yes, then announcement is created.
  429.               valid = (choice == JOptionPane.YES_OPTION);
  430.          }
  431.          return valid;
  432.     }
  433. }
  434.  
  435. // this single line of code is the script's main routine
  436. // it calls the methods and exits
  437. if( buffer.getMode().toString().equals( "properties" ) )
  438.     pluginTextDialog( view, buffer );
  439. else
  440.     Macros.error( view, "This must be run on a jEdit plugin's properties file.  \nOpen your Plugin's props file and rerun this macro." );
  441.  
  442. // ::mode=beanshell:noTabs=true:tabSize=4:indentSize=4::
  443.